package com.atguigu.aclservice.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.aclservice.entity.Permission;
import com.atguigu.aclservice.entity.RolePermission;
import com.atguigu.aclservice.entity.User;
import com.atguigu.aclservice.helper.MemuHelper;
import com.atguigu.aclservice.helper.PermissionHelper;
import com.atguigu.aclservice.mapper.PermissionMapper;
import com.atguigu.aclservice.service.PermissionService;
import com.atguigu.aclservice.service.RolePermissionService;
import com.atguigu.aclservice.service.UserService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 权限 服务实现类
 * </p>
 *
 * @author testjava
 * @since 2020-01-12
 */
@Service
public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, Permission> implements PermissionService {

    @Autowired
    private RolePermissionService rolePermissionService;

    @Autowired
    private UserService userService;

    //根据角色获取菜单
    @Override
    public List<Permission> selectAllMenu(String roleId) {
        List<Permission> allPermissionList = baseMapper.selectList(new QueryWrapper<Permission>().orderByAsc("CAST(id AS SIGNED)"));

        //根据角色id获取角色权限
        List<RolePermission> rolePermissionList = rolePermissionService.list(new QueryWrapper<RolePermission>().eq("role_id", roleId));
        //转换给角色id与角色权限对应Map对象
//        List<String> permissionIdList = rolePermissionList.stream().map(e -> e.getPermissionId()).collect(Collectors.toList());
//        allPermissionList.forEach(permission -> {
//            if(permissionIdList.contains(permission.getId())) {
//                permission.setSelect(true);
//            } else {
//                permission.setSelect(false);
//            }
//        });
        for (int i = 0; i < allPermissionList.size(); i++) {
            Permission permission = allPermissionList.get(i);
            for (int m = 0; m < rolePermissionList.size(); m++) {
                RolePermission rolePermission = rolePermissionList.get(m);
                if (rolePermission.getPermissionId().equals(permission.getId())) {
                    permission.setSelect(true);
                }
            }
        }


        List<Permission> permissionList = bulid(allPermissionList);
        return permissionList;
    }

    /**
     * 使用递归方法建菜单
     *
     * @param treeNodes
     * @return
     */
    private static List<Permission> bulid(List<Permission> treeNodes) {
        List<Permission> trees = new ArrayList<>();
        for (Permission treeNode : treeNodes) {
            if ("0".equals(treeNode.getPid())) {
                treeNode.setLevel(1);
                trees.add(findChildren(treeNode, treeNodes));
            }
        }
        return trees;
    }

    /**
     * 递归查找子节点
     *
     * @param treeNodes
     * @return
     */
    private static Permission findChildren(Permission treeNode, List<Permission> treeNodes) {
        treeNode.setChildren(new ArrayList<Permission>());

        for (Permission it : treeNodes) {
            if (treeNode.getId().equals(it.getPid())) {
                int level = treeNode.getLevel() + 1;
                it.setLevel(level);
                if (treeNode.getChildren() == null) {
                    treeNode.setChildren(new ArrayList<>());
                }
                treeNode.getChildren().add(findChildren(it, treeNodes));
            }
        }
        return treeNode;
    }


    /**
     * //========================递归查询所有菜单================================================
     * //获取全部菜单
     *
     * @return
     */
    @Override
    public List<Permission> queryAllMenuGuli() {
        //1, 查询菜单表的所有数据
        QueryWrapper<Permission> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("id");
        List<Permission> permissionList = baseMapper.selectList(wrapper);
        //把查询出来的所有菜单List集合按要求封装
        List<Permission> resultList = buildPermission(permissionList);
        return resultList;
    }

    /**
     * 把返回的所有菜单的list集合使用递归按照层次封装
     *
     * @param permissionList
     * @return
     */
    public static List<Permission> buildPermission(List<Permission> permissionList) {
        //创建list集合，用于数据最终封装
        List<Permission> finalNode = new ArrayList<>();

        //遍历所有菜单list集合 ， 得到Pid=0的菜单， 设置level为1
        for (Permission permission : permissionList) {
            if ("0".equals(permission.getPid())) {
                permission.setLevel(1);
                finalNode.add(selectChildren(permission, permissionList));
            }
        }
        return finalNode;
    }


    private static Permission selectChildren(Permission permissionNode, List<Permission> permissionList) {
        permissionNode.setChildren(new ArrayList<Permission>());
        for (Permission permission : permissionList) {
            if (permission.getPid().equals(permissionNode.getId())) {
                int level = permissionNode.getLevel() + 1;
                permission.setLevel(level);
                permissionNode.getChildren().add(selectChildren(permission, permissionList));
            }
        }
        return permissionNode;
    }

    @Override
    public void removeChildByIdGuli(String id) {

        //创建集合用于封装所有需要删除的菜单id
        List<String> ids = new ArrayList<>();
        //向ids设置要删除的菜单id
        //递归
        selectPermissionChildById(id, ids);
        ids.add(id);
        baseMapper.deleteBatchIds(ids);
    }

    //根据当前菜单id，查询子菜单的id，封装到list集合
    private void selectPermissionChildById(String id, List<String> ids) {
        QueryWrapper<Permission> wrapper = new QueryWrapper<>();
        wrapper.eq("pid", id);
        wrapper.select("id");
        List<Permission> permissions = baseMapper.selectList(wrapper);
        //1，循环递归删除
//        for (Permission permission : permissions) {
//            ids.add(permission.getId());
//            selectPermissionChildById(permission.getId(),ids);
//        }

        //2， 流
        //遍历permissions 获取每个对象 item
        permissions.stream().forEach(item -> {
            //封装ids
            ids.add(item.getId());
            //递归查询
            this.selectPermissionChildById(item.getId(), ids);
        });
    }

    //给角色分配菜单
    @Override
    public void saveRolePermissionRelationShipGuli(String roleId, String[] permissionId) {
        //创建list集合用于封装添加数据
        List<RolePermission> rolePermissions = new ArrayList<>();
        for (String pid : permissionId) {
            RolePermission rolePermission = new RolePermission();
            //设置rolePermission对象的属性
            rolePermission.setRoleId(roleId);
            rolePermission.setPermissionId(pid);
            //封装到list
            rolePermissions.add(rolePermission);
        }
        rolePermissionService.saveBatch(rolePermissions);
    }

    @Override
    public List<String> selectPermissionValueByUserId(String id) {

        List<String> selectPermissionValueList = null;
        if (this.isSysAdmin(id)) {
            //如果是系统管理员，获取所有权限
            selectPermissionValueList = baseMapper.selectAllPermissionValue();
        } else {
            selectPermissionValueList = baseMapper.selectPermissionValueByUserId(id);
        }
        return selectPermissionValueList;
    }


    /**
     * 判断用户是否系统管理员
     *
     * @param userId
     * @return
     */
    private boolean isSysAdmin(String userId) {
        User user = userService.getById(userId);

        if (null != user && "admin".equals(user.getUsername())) {
            return true;
        }
        return false;
    }

    @Override
    public List<JSONObject> selectPermissionByUserId(String userId) {
        List<Permission> selectPermissionList = null;
        if (this.isSysAdmin(userId)) {
            //如果是超级管理员，获取所有菜单
            selectPermissionList = baseMapper.selectList(null);
        } else {
            selectPermissionList = baseMapper.selectPermissionByUserId(userId);
        }

        List<Permission> permissionList = PermissionHelper.bulid(selectPermissionList);
        List<JSONObject> result = MemuHelper.bulid(permissionList);
        return result;
    }
}
